export = {}

class Parent {
  address:string = '回龙观'
}

class Child extends Parent{
  money:number = 100
}

class Grandson extends Child{
  name:string = 'Tom'
}

type MyFn = (person: Child) => Child

function getFn(cb: MyFn) {

}

/** 逆变(可传父) 针对于参数*/
// getFn((person:Child)=>new Child) //√
getFn((person:Parent/*逆变：参数可以传父*/)=>new Child) //√
getFn((person:Grandson)=>new Child) //Property 'name' is missing in type 'Child' but required in type 'Grandson'.
/** ↑ 其实就是对象的情况 多的可以赋给少的 但少的不能赋给多的*/

/** 协变(可反子) 针对于返回值*/
getFn((person:Parent)=>new Parent) //Property 'money' is missing in type 'Parent' but required in type 'Child'.
getFn((person:Parent)=>new Grandson/*协变: 返回值可以传子*/) //√


//协变和逆变 也是基于安全性考虑 才这样设计的
//接的时候可以少接点, 但返回的东西一定要不少于期望的

/** 双向协变 就是可以传儿子 也可以传父亲 默认在严格模式下不支持
 *  不推荐, 因为这样就相当于不校验了 */
// 需要将 "strictFunctionTypes" 置为 false


//应用举例
/** case1 */
// function getFn2(cb: (person: string | number) => number|string){
//
// }
// getFn2((person:string|number|boolean)=>'xx')
/** case2 */

